package com.ys.timer;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.config.MyConfig;
import com.ys.entity.advanced.AdsReportLog;
import com.ys.entity.advanced.Profiles;
import com.ys.entity.base.TbSite;
import com.ys.entity.business.TpAmazonSeller;
import com.ys.entity.business.TpAmazonShop;
import com.ys.entity.hr.ThrOperateCompanyApply;
import com.ys.entity.sys.TbStaticConfig;
import com.ys.enume.advanced.MarketplaceEnum;
import com.ys.enume.MarketPlaceEnum;
import com.ys.enume.advanced.ReportTypeEnum;
import com.ys.mapper.business.DiySqlMapper;
import com.ys.mapper.sys.TbStaticConfigMapper;
import com.ys.service.advanced.AdsSpServise;
import com.ys.service.log.ApiLogService;
import com.ys.util.ApiHttpUtils;
import com.ys.util.RedisUtil;
import com.ys.util.dhecp.StringUtils;
import com.ys.vo.ApiResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 自动获取亚马逊api广告定时器
 */
@Controller
public class TimerAdvancedApiDataDaily {
	private static Logger logger = LoggerFactory.getLogger(TimerAdvancedApiDataDaily.class);


	@Autowired
	private AdsSpServise adsSpServise;


	@Autowired
	private DiySqlMapper diySqlMapper;

	@Autowired
	private ApiLogService apiLogService;

	@Autowired
	private RedisUtil redisUtil;

	@Autowired
	private TbStaticConfigMapper tbStaticConfigMapper;


	/**
	 * 定时早上8点创建欧洲站广告请求
	 */
//	@Scheduled(cron = "0 0 8 * * ?  ")
	public void getYgReport0() {
		getYgReport(0);
	}

	/**
	 * 定时下午15点创建北美站广告请求
	 */
//	@Scheduled(cron = "0 0 15 * * ?  ")
	public void getYgReport1() {
		getYgReport(1);
	}

	/**
	 * 定时中午12点获取英国站广告数据
	 */
//	@Scheduled(cron = "0 30 8 * * ?  ")
	public void getHqReport0() {
		getReport(0);
	}

	/**
	 * 定时下午16点获取美国站广告数据
	 */
//	@Scheduled(cron = "0 30 15 * * ?  ")
	public void getHqReport1() {
		getReport(1);
	}

	/**
	 * 定时中午12点30分同步非广告商品订单的广告id
	 */
//	@Scheduled(cron = "0 0,0 9,16 * * ? ")
	public void getSynchronousAdId() {
		logger.info("***********每日定时同步非广告商品订单的广告id,开始***********");
		Map<Object, Object> redisMap = redisUtil.hGetAll("THREAD_REPORT");
		boolean variable = true;
		while (variable) {
			if (redisMap.size() == 0){
				break;
			}
			for (Map.Entry<Object, Object> e : redisMap.entrySet()) {
				if (e.getValue().equals("1")) {
					try {
						Thread.sleep(10000L);
					} catch (InterruptedException ex) {
						ex.printStackTrace();
					}
					continue;
				} else if (e.getValue().equals("0")) {
					variable = false;
				}
			}
		}
		ApiResponse apiResponse = adsSpServise.getSynchronousAdId();
		if (apiResponse.getCode() == 400) {
			apiLogService.addApiLog("Amazon", "getSynchronousAdId", "ECP_API定时同步非广告商品订单的广告id", "", apiResponse.getCode(), apiResponse.getMessage());
		}
		//刷新时间
		TbStaticConfig tbStaticConfig = new TbStaticConfig()
				.where("A.KeyOne = 'refresh-amazon-advert' AND A.KeyTwo = 'finishi-time'")
				.queryFirst();
		if (tbStaticConfig != null){
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			// 获取当前时间
			Date currentTime = new Date();
			// 将当前时间转换为字符串
			String currentTimeString = sdf.format(currentTime);
			tbStaticConfig.setName(currentTimeString);
			tbStaticConfigMapper.update(tbStaticConfig);
		}
		logger.info("***********每日定时同步非广告商品订单的广告id,结束***********");
	}

	/**
	 * 定时下午18点获取北美站广告数据
	 */
	public void getReport1() {
		getReport(1);
	}

	public void getReport(Integer type) {
		logger.info("***********每日定时获取广告,开始***********");
		Map<Object, Object> redisMapNew = redisUtil.hGetAll("THREAD_MAPASIN");
		boolean variableNew = true;
		while (variableNew) {
			if (redisMapNew.size() == 0){
				break;
			}
			for (Map.Entry<Object, Object> e : redisMapNew.entrySet()) {
				if (e.getValue().equals("1")) {
					try {
						Thread.sleep(10000L);
					} catch (InterruptedException ex) {
						ex.printStackTrace();
					}
					continue;
				} else if (e.getValue().equals("0")) {
					variableNew = false;
				}
			}
		}
		ApiResponse apiResponse = new ApiResponse();
		try {
			//获取店铺广告已授权信息
			List<Map<String, Object>> tpAmazonShopList = new TpAmazonShop()
					.addLeftJoin("TP_AmazonSeller tsell on tsell.id = A.AmazonSellerId")//卖家管理
					.addField("tsell.refreshTokenGg as refreshTokenGg,tsell.regionCode as regionCode,tsell.regionName,tsell.vgsbm as vgsbm,tsell.vgsjc as vgsjc")
					.addLeftJoin("TB_Site ts on ts.id = A.SiteId")//站点
					.addField("ts.AmazonMarketplaceId AS marketplaceId,ts.amazonAuthUrlGg amazonAuthUrlGg,ts.amazonApiUrlGg amazonApiUrlGg")
					.addLeftJoin("TB_Country tbc on tbc.id = ts.CountryId")//国家
					.where("tsell.authorizeStateGg = '已授权' AND tbc.Name IN ('德国','英国','美国')" + " AND tsell.Status = 1")
					.queryMap();
			for (int i = 0; i < 20; i++) {
				redisUtil.hPut("THREAD_REPORT", String.valueOf(i), "0");
			}
			JSONArray jsonArrayOb = JSONArray.parseArray(JSON.toJSONString(tpAmazonShopList));
			for (int j = 0; j < jsonArrayOb.size(); j++) {
				JSONObject jsonObjectOb = jsonArrayOb.getJSONObject(j);
				List<AdsReportLog> adsReportLogList = new AdsReportLog().
						where("A.ShopId = '" + jsonObjectOb.get("id").toString() + "'")
						.setOrderby("A.reportType asc")
						.queryList();
				if (adsReportLogList.size() == 0) {
					continue;
				}
				//查询备案公司
				ThrOperateCompanyApply thrOperateCompanyApply = new ThrOperateCompanyApply()
						.where("A.vGsBm = '" + jsonObjectOb.get("vgsbm").toString() + "'")
						.queryFirst();
				if (thrOperateCompanyApply == null) {
					continue;
				}

				//获取新的token
				Map<String, String> postMapParams = new HashMap<>();
				postMapParams.put("grant_type", "refresh_token");
				postMapParams.put("client_id", MyConfig.getAmazonClientId());
				postMapParams.put("client_secret", MyConfig.getAmazonClientSecret());
				postMapParams.put("refresh_token", jsonObjectOb.get("refreshTokenGg").toString());
				JSONObject jsonObject = ApiHttpUtils.sendHttpClientPost(jsonObjectOb.get("amazonAuthUrlGg").toString(), postMapParams);
				String error = "";
				if (jsonObject != null) {
					if (jsonObject.containsKey("error")) {
						error = jsonObject.getString("error");
					}
					if (StringUtils.isEmpty(error)) {
						//获取配置文件id
						Map<String, String> getMapParams = new HashMap<>();
						getMapParams.put("Amazon-Advertising-API-ClientId", MyConfig.getAmazonClientId());
						getMapParams.put("Authorization", jsonObject.getString("access_token"));
						for (AdsReportLog adsReportLog : adsReportLogList) {
							getMapParams.put("Amazon-Advertising-API-Scope", adsReportLog.getProfileId());
							boolean variable = true;
							while (variable) {
								Map<Object, Object> redisMap = redisUtil.hGetAll("THREAD_REPORT");
								for (Map.Entry<Object, Object> e : redisMap.entrySet()) {
									if (e.getValue().equals("1")) {
										continue;
									} else if (e.getValue().equals("0")) {
										redisUtil.hPut("THREAD_REPORT", String.valueOf(e.getKey()), "1");
										// 开启线程
										Thread t = new Thread(() -> {
											//获取报告
											ApiResponse apiResponse1 = adsSpServise.getReports(jsonObjectOb, getMapParams, adsReportLog,thrOperateCompanyApply);
											if (apiResponse1.getCode() == 400) {
												apiLogService.addApiLog("Amazon", "getSpPurchasedProduct", "ECP_API定时获取亚马逊广告报告出错，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), apiResponse1.getCode(), apiResponse1.getMessage());
											}
											redisUtil.delete(adsReportLog.getReportId());
											redisUtil.hPut("THREAD_REPORT", String.valueOf(e.getKey()), "0");
										});
										t.start();
//										Thread.sleep(1000L);
									}
									variable = false;
									break;
								}
							}
						}
					}else {
						if (jsonObject.getString("code").equals("429")){
							Integer redis = 0;
							if(redisUtil.get(jsonObjectOb.get("guid").toString())!= null && !redisUtil.get(jsonObjectOb.get("guid").toString()).equals("")) {
								redis = Integer.valueOf(redisUtil.get(jsonObjectOb.get("guid").toString()));
							}
							redisUtil.set(jsonObjectOb.get("guid").toString(),String.valueOf(redis+1000));
						}else {
							apiResponse.setCode(400);
							apiResponse.setMessage("获取亚马逊获取报告失败，具体原因为" + jsonObject);
							apiLogService.addApiLog("Amazon", "getProfiles", "ECP_API定时获取亚马逊广告报告出错，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), apiResponse.getCode(), apiResponse.getMessage());
							continue;
						}
					}
				} else {
					apiResponse.setCode(400);
					apiResponse.setMessage("获取亚马逊TOKEN失败，具体原因为" + jsonObject);
					apiLogService.addApiLog("Amazon", "getProfiles", "ECP_API定时获取亚马逊广告报告出错，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), apiResponse.getCode(), apiResponse.getMessage());
				}
			}
		}catch (Exception e) {
			apiResponse.setCode(500);
			apiResponse.setMessage("获取亚马逊广告失败，具体原因为" + e.getMessage());
			apiLogService.addApiLog("Amazon", "getReport", "ECP_API定时获取亚马逊广告报告出错", "", apiResponse.getCode(), apiResponse.getMessage());
		}
		logger.info("***********每日定时获取广告,结束***********");
	}

	private void getYgReport(int type){
		logger.info("***********每日定时创建广告报告,开始***********");

		try {
			ApiResponse apiResponse = new ApiResponse();
			SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd");
			//获取昨天时间和前7天时间
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.DATE, -1);
			String dateOne = inputFormat.format(calendar.getTime());

			Calendar calendar1 = Calendar.getInstance();
			calendar1.add(Calendar.DATE, -7);
			String dateFourteen = inputFormat.format(calendar1.getTime());
			List<String> dateList = new ArrayList<>();
			dateList.add(dateOne);
			dateList.add(dateFourteen);
			//每天删除之前的创建报告的记录
			diySqlMapper.delADSReportLog();
			String regionCode = "";
			if (type == 0){
				regionCode = " AND tsell.regionCode = 'EUROPE'";
			} else if (type == 1){
				regionCode = " AND tsell.regionCode = 'NORTH'";
			}
			List<Map<String, Object>> tpAmazonShopList = new TpAmazonShop()
					.addLeftJoin("TP_AmazonSeller tsell on tsell.id = A.AmazonSellerId")//卖家管理
					.addField("tsell.refreshTokenGg as refreshTokenGg,tsell.regionCode as regionCode,tsell.regionName,tsell.vgsbm as vgsbm")
					.addLeftJoin("TB_Site ts on ts.id = A.SiteId")//站点
					.addField("ts.AmazonMarketplaceId AS marketplaceId,ts.amazonAuthUrlGg amazonAuthUrlGg,ts.amazonApiUrlGg amazonApiUrlGg")
					.where("tsell.authorizeStateGg = '已授权'" + regionCode + " AND tsell.Status = 1")
					.queryMap();
			for (int i = 0; i < 20; i++) {
				redisUtil.hPut("THREAD_MAPASIN",String.valueOf(i),"0");
			}
			JSONArray jsonArrayOb = JSONArray.parseArray(JSON.toJSONString(tpAmazonShopList));
			for (int j = 0; j < jsonArrayOb.size(); j++) {
				JSONObject jsonObjectOb = jsonArrayOb.getJSONObject(j);
				boolean variable = true;
				while (variable) {
					Map<Object, Object> redisMap = redisUtil.hGetAll("THREAD_MAPASIN");
					for (Map.Entry<Object, Object> e : redisMap.entrySet()) {
						if (e.getValue().equals("1")) {
							continue;
						} else if (e.getValue().equals("0")) {
							redisUtil.hPut("THREAD_MAPASIN", String.valueOf(e.getKey()),"1");
//							开启线程
							Thread t = new Thread(() -> {
								//获取新的token
								Map<String, String> postMapParams = new HashMap<>();
								postMapParams.put("grant_type", "refresh_token");
								postMapParams.put("client_id", MyConfig.getAmazonClientId());
								postMapParams.put("client_secret", MyConfig.getAmazonClientSecret());
								postMapParams.put("refresh_token", jsonObjectOb.get("refreshTokenGg").toString());
								JSONObject jsonObject = ApiHttpUtils.sendHttpClientPost(jsonObjectOb.get("amazonAuthUrlGg").toString(), postMapParams);
								String error = "";
								if (jsonObject != null) {
									if (jsonObject.containsKey("error")) {
										error = jsonObject.getString("error");
									}
									if (StringUtils.isEmpty(error)) {
										String access_token = jsonObject.getString("access_token");
										//获取配置文件id
										Map<String, String> getMapParams = new HashMap<>();
										getMapParams.put("Amazon-Advertising-API-ClientId", MyConfig.getAmazonClientId());
										getMapParams.put("Authorization", access_token);
										String errorGet = "";
										jsonObject = ApiHttpUtils.sendHttpClientGet(jsonObjectOb.get("amazonApiUrlGg").toString() + "/v2/profiles", getMapParams);
										if (jsonObject != null) {
											if (jsonObject.containsKey("error")) {
												errorGet = jsonObject.getString("error");
											}
											if (StringUtils.isEmpty(errorGet)) {
												JSONArray jsonArray = JSON.parseArray(jsonObject.get("data").toString());
												for (int i = 0; i < jsonArray.size(); i++) {
													Profiles profiles = JSON.parseObject(jsonArray.get(i).toString(), Profiles.class);
													//排除德国、英国、美国以外的站点数据不需要获取
													if (!profiles.getCountryCode().equals(MarketPlaceEnum.DE.code)
															&& !profiles.getCountryCode().equals(MarketPlaceEnum.GB3.code)
															&& !profiles.getCountryCode().equals(MarketPlaceEnum.US.code)
															){
														continue;
													}
													for (String date : dateList) {
														//查询对应的店铺信息
														TpAmazonShop tpAmazonShop1 = new TpAmazonShop()
																.addLeftJoin("TP_AmazonSeller tsell on tsell.id = A.AmazonSellerId")//卖家管理
																.addLeftJoin("TB_Site ts on ts.id = A.SiteId")//站点
																.where("ts.AmazonMarketplaceId = '" + profiles.getAccountInfo().get(0).getMarketplaceStringId()
																+ "' AND tsell.Vgsbm = '" + jsonObjectOb.get("vgsbm").toString() +"' AND A.SellerId = '" + profiles.getAccountInfo().get(0).getId() + "'").queryFirst();
														if (tpAmazonShop1 == null){
															apiLogService.addApiLog("Amazon", "getProfiles", "ECP_API定时获取亚马逊广告报告未知，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), 500, "配置文件信息 :" + JSON.toJSONString(profiles));
															continue;
														}
														//创建广告活动预算表报告
														ApiResponse apiResponse1 = adsSpServise.getSpCampaigns(tpAmazonShop1, profiles, getMapParams, jsonObjectOb, date, ReportTypeEnum.SPCAMPAIGNS.getNum());
														if (apiResponse1.getCode() == 400) {
															apiLogService.addApiLog("Amazon", "getSpCampaigns", "ECP_API定时获取亚马逊广告报告出错，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), apiResponse1.getCode(), apiResponse1.getMessage());
														}
														//创建赞助产品活动及展示位置总结报告
														apiResponse1 = adsSpServise.getSpCampaignsWithPlacement(tpAmazonShop1, profiles, getMapParams, jsonObjectOb, date, ReportTypeEnum.WithPlacement.getNum());
														if (apiResponse1.getCode() == 400) {
															apiLogService.addApiLog("Amazon", "getSpCampaignsWithPlacement", "ECP_API定时获取亚马逊广告报告出错，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), apiResponse1.getCode(), apiResponse1.getMessage());
														}
														//创建赞助产品关键词和定位
														apiResponse1 = adsSpServise.getSpTargeting(tpAmazonShop1, profiles, getMapParams, jsonObjectOb, date, ReportTypeEnum.TARGETING.getNum());
														if (apiResponse1.getCode() == 400) {
															apiLogService.addApiLog("Amazon", "getSpTargeting", "ECP_API定时获取亚马逊广告报告出错，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), apiResponse1.getCode(), apiResponse1.getMessage());
														}
														//创建广告组搜索词表
														apiResponse1 = adsSpServise.getSpSearchTerm(tpAmazonShop1, profiles, getMapParams, jsonObjectOb, date, ReportTypeEnum.SEARCHTERM.getNum());
														if (apiResponse1.getCode() == 400) {
															apiLogService.addApiLog("Amazon", "getSpSearchTerm", "ECP_API定时获取亚马逊广告报告出错，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), apiResponse1.getCode(), apiResponse1.getMessage());
														}
														//创建广告商品表
														apiResponse1 = adsSpServise.getSpAdvertisedProduct(tpAmazonShop1, profiles, getMapParams, jsonObjectOb, date, ReportTypeEnum.ADVERTISEDPRODUCT.getNum());
														if (apiResponse1.getCode() == 400) {
															apiLogService.addApiLog("Amazon", "getSpAdvertisedProduct", "ECP_API定时获取亚马逊广告报告出错，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), apiResponse1.getCode(), apiResponse1.getMessage());
														}
														//创建非广告商品订单情况表
														apiResponse1 = adsSpServise.getSpPurchasedProduct(tpAmazonShop1, profiles, getMapParams, jsonObjectOb, date, ReportTypeEnum.PURCHASEDPRODUCT.getNum());
														if (apiResponse1.getCode() == 400) {
															apiLogService.addApiLog("Amazon", "getSpPurchasedProduct", "ECP_API定时获取亚马逊广告报告出错，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), apiResponse1.getCode(), apiResponse1.getMessage());
														}
													}
												}
											} else {
												String errorDescription = jsonObject.getString("message");
												apiResponse.setCode(400);
												apiResponse.setMessage("获取亚马逊配置文件失败，具体原因为" + errorDescription);
												apiLogService.addApiLog("Amazon", "getSpPurchasedProduct", "ECP_API定时获取亚马逊广告报告出错，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), apiResponse.getCode(), apiResponse.getMessage());
											}
										} else {
											apiResponse.setCode(400);
											apiResponse.setMessage("获取亚马逊配置文件失败！");
											apiLogService.addApiLog("Amazon", "getSpPurchasedProduct", "ECP_API定时获取亚马逊广告报告出错，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), apiResponse.getCode(), apiResponse.getMessage());
										}
									} else {
										String errorDescription = jsonObject.getString("message");
										apiResponse.setCode(400);
										apiResponse.setMessage("获取亚马逊TOKEN失败，具体原因为" + errorDescription);
										apiLogService.addApiLog("Amazon", "getSpPurchasedProduct", "ECP_API定时获取亚马逊广告报告出错，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), apiResponse.getCode(), apiResponse.getMessage());
									}
								} else {
									apiResponse.setCode(400);
									apiResponse.setMessage("获取亚马逊TOKEN失败！");
									apiLogService.addApiLog("Amazon", "getSpPurchasedProduct", "ECP_API定时获取亚马逊广告报告出错，条件queryParams：" + JSON.toJSONString(jsonObjectOb), "店铺:" + jsonObjectOb.get("shopName").toString(), apiResponse.getCode(), apiResponse.getMessage());
								}
								redisUtil.hPut("THREAD_MAPASIN", String.valueOf(e.getKey()),"0");
							});
							t.start();
							Thread.sleep(1000L);
						}
						variable = false;
						break;
					}
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		logger.info("***********每日定时创建广告报告,结束***********");
	}
}
